#include "stdafx.h"
#include "MsgRouter.h"
#include "../../NSNetLibSrc/Framework/ServerFramework/ServerFramework_Architecture.h"

MsgRoutingTarget::MsgRoutingTarget() : server_body_(NULL), server_cord_(NULL)
{
}

bool MsgRoutingTarget::Send(CMsg* msg)
{
	if (IS_CRITICAL(g_pNetEngine->SendMsg(server_cord_->m_dwSessionID, msg))) {
		return false;
	}
	return true;
}

MsgRoutingTable MsgRouter::table_;

MsgRouter::MsgRouter() : active_content_(UCHAR_MAX)
{
	contens_targets_.resize(UCHAR_MAX);
}

MsgRouter::~MsgRouter()
{
	server_targets_.clear();
	contens_targets_.clear();
}

void MsgRouter::Reset()
{
	active_content_ = UCHAR_MAX;
	if (!server_targets_.empty()) {
		for each(MAP_TARGETS::value_type target_iter in server_targets_) {
			new (target_iter.second) MsgRoutingTarget;
		}
		server_targets_.clear();
	}
}

bool MsgRouter::Register(unsigned char content_id, sServerBody* server_body)
{
	if (content_id == USHRT_MAX) {
		return false;
	}

	if (server_body == NULL) {
		return false;
	}

	sServerCord* server_cord = FindServerCordToRouteServer(server_body->m_nID);
	if (server_cord == NULL) {
		return false;
	}

	MsgRoutingTarget& target = contens_targets_[content_id];
	std::pair<MAP_TARGETS::iterator, bool> target_iter = server_targets_.insert(MAP_TARGETS::value_type(server_body->m_nID, &target));
	if (!target_iter.second) {
		return false;
	}

	target.Redirection(server_body, server_cord);
	return true;
}

void MsgRouter::UnRegister(unsigned char content_id)
{
	MsgRoutingTarget* target = FindContentTarget(content_id);
	if (target != nullptr)
		server_targets_.erase(target->server_id());
}

bool MsgRouter::Register(unsigned char content_id, unsigned long server_id)
{
	return Register(content_id, FindServerBody(server_id));
}

bool MsgRouter::Send(CMsg* msg)
{
	unsigned char content_id = table_.content_id_[msg->GetMsgID()];
	if (content_id == UCHAR_MAX) {
		if (active_content_ == UCHAR_MAX) {
			return false;
		}
		content_id = active_content_;
	}

	MsgRoutingTarget& target = contens_targets_[content_id];
	if (target.IsNotExist()) {
		return false;
	}

	return target.Send(msg);
}

MsgRoutingTarget* MsgRouter::FindContentTarget(unsigned char content_id)
{
	MsgRoutingTarget& target = contens_targets_[content_id];
	if (target.IsNotExist()) {
		return NULL;
	}
	return &target;
}

MsgRoutingTarget* MsgRouter::FindServerTarget(unsigned long server_id)
{
	MAP_TARGETS::iterator target_iter = server_targets_.find(server_id);
	if (target_iter == server_targets_.end()) {
		return NULL;
	}
	return target_iter->second;
}